package views;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.sql.Date;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

import javax.swing.*;
import javax.swing.event.CellEditorListener;
import javax.swing.event.ChangeEvent;
import javax.swing.table.*;

import controllers.Driver;
import controllers.EventHandler;
import controllers.MyTableModel;
import controllers.Event;
import controllers.Vehicle;
import db.DriverDAO;
import db.EventDAO;
import db.VehicleDAO;

public class mainFrame extends JFrame {

    private final static String TITLE = "CSSA Van Scheduling";
    private static final int WIDTH = 1000;
    private static final int HEIGHT = 650;
    private static final int XBOUND = 50;
    private static final int YBOUND = 50;
    private static JMenuBar menuBar;
    private static JLabel dateLabel;
    static List<controllers.Event> eventsList;
    public static myTable table;
    private static MyTableModel model;
    private static Object[][] events;
    private static Object[] columnNames = {"Date", "Drive Time", "Depart JCU", "Driver", "Transportation", "Service Time", "Site", "# attending", "Return JCU"};
    private static JScrollPane scrollpane;
    private static SimpleDateFormat sdf = new SimpleDateFormat("EEE, MMM dd");
    private static SimpleDateFormat sdf2 = new SimpleDateFormat("hh:mm a");
    private static SimpleDateFormat sdf3 = new SimpleDateFormat("EEEE, MMMM dd, yyyy");
    private static Calendar cal = Calendar.getInstance();
    static int selectedIndex;
    private static Driver[] driverArray;
    private static JButton back, forward, goToToday;
    public static Container content;
    private String dayOrWeek = "Week of ";
    private static JRadioButton weekly, daily;
    private static boolean weeklybool = true;

    public mainFrame() {

        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setTitle(TITLE);
        this.setBounds(XBOUND, YBOUND, WIDTH, HEIGHT);
        this.setResizable(false);
        content = this.getContentPane();
        content.setLayout(null);
        //content.setBackground(new Color(00,33,66));

        scrollpane = new JScrollPane();
        content.add(scrollpane);
        updateTable();

        List<Driver> driverList = DriverDAO.getDrivers();
        driverArray = new Driver[driverList.size()];

        for (int i = 0; i < driverList.size(); i++) {
            driverArray[i] = driverList.get(i);
        }

        cal.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);
        dateLabel = new JLabel(dayOrWeek + sdf3.format(cal.getTimeInMillis()));
        dateLabel.setBounds(50, 15, 700, 30);
        dateLabel.setFont(new java.awt.Font("Tahoma", 1, 24));
        content.add(dateLabel);

        back = new JButton(" << ");
        back.setBounds(50, 460, 100, 30);
        back.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                if (weeklybool) {
                    cal.setTimeInMillis(cal.getTimeInMillis() - (60 * 60 * 1000 * 24 * 7));
                } else {
                    cal.setTimeInMillis(cal.getTimeInMillis() - (60 * 60 * 1000 * 24));
                }
                dateLabel.setText(dayOrWeek + sdf3.format(cal.getTimeInMillis()));

                if (!forward.isEnabled()) {
                    forward.setEnabled(true);
                }

                updateTable();
            }
        });
        content.add(back);

        forward = new JButton(" >> ");
        forward.setBounds(160, 460, 100, 30);
        forward.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                if (weeklybool) {
                    cal.setTimeInMillis(cal.getTimeInMillis() + (60 * 60 * 1000 * 24 * 7));
                    if (cal.getTimeInMillis() > Calendar.getInstance().getTimeInMillis() + 60 * 60 * 1000 * 24 * 14) {
                        forward.setEnabled(false);
                    }
                } else {
                    cal.setTimeInMillis(cal.getTimeInMillis() + (60 * 60 * 1000 * 24));
                    if (cal.getTimeInMillis() > Calendar.getInstance().getTimeInMillis() + 60 * 60 * 1000 * 24 * 14) {
                        forward.setEnabled(false);
                    }
                }
                updateTable();

                dateLabel.setText(dayOrWeek + sdf3.format(cal.getTimeInMillis()));
            }
        });
        content.add(forward);

        goToToday = new JButton("Go to Today");
        goToToday.setBounds(270, 460, 100, 30);
        goToToday.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                cal = Calendar.getInstance();
                dateLabel.setText(dayOrWeek + sdf3.format(cal.getTimeInMillis()));
                updateTable();
            }
        });
        content.add(goToToday);

        weekly = new JRadioButton("Weekly");
        weekly.setBounds(50, 500, 100, 20);
        weekly.setSelected(true);
        weekly.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                dayOrWeek = "Week Of ";
                dateLabel.setText(dayOrWeek + sdf3.format(cal.getTimeInMillis()));
                weeklybool = true;
                updateTable();
            }
        });
        daily = new JRadioButton("Daily");
        daily.setBounds(50, 525, 100, 20);
        daily.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                dayOrWeek = "";
                dateLabel.setText(dayOrWeek + sdf3.format(cal.getTimeInMillis()));
                weeklybool = false;
                updateTable();
            }
        });

        ButtonGroup bg = new ButtonGroup();
        bg.add(weekly);
        bg.add(daily);

        content.add(weekly);
        content.add(daily);


        menuBar = new JMenuBar();

        JMenu file = new JMenu("File");

        JMenuItem GenerateNextWeek = new JMenuItem("Generate Next Week");
        GenerateNextWeek.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent arg0) {
                if (cal.getTimeInMillis() < Calendar.getInstance().getTimeInMillis()) {
                    Object[] options = {"No, Don't Regenerate", "Yes, Regenerate"};
                    int choice = JOptionPane.showOptionDialog(getComponent(0), "Are you sure you want to generate events for this week in the past?", "Regenerate?", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE, null, options, options[1]);
                    switch (choice) {
                        case 0:
                            break;
                        case 1:
                                //new ProgressBar(getX() + WIDTH / 2, getY() + HEIGHT / 2, cal, weeklybool).setVisible(true);
                                        Calendar temp = cal;
            for (int i = 0; i < 7; i++) {
                new EventHandler(temp);
                temp.setTimeInMillis(temp.getTimeInMillis() + (1000 * 60 * 60 * 24));
                //ProgressBar.eventDone();
            }
                            break;

                        default:
                            break;
                    }
                } else {
                    //new ProgressBar(getX() + WIDTH / 2, getY() + HEIGHT / 2, cal, weeklybool).setVisible(true);
                            Calendar temp = cal;
            for (int i = 0; i < 7; i++) {
                new EventHandler(temp);
                temp.setTimeInMillis(temp.getTimeInMillis() + (1000 * 60 * 60 * 24));
                //ProgressBar.eventDone();
            }
                }
            }
        });
        file.add(GenerateNextWeek);
        file.add(new JSeparator());

        JMenuItem Exit = new JMenuItem("Exit");
        Exit.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                System.exit(0);
            }
        });
        file.add(Exit);

        JMenu drivers = new JMenu("Drivers");
        JMenuItem addDriver = new JMenuItem("Add Driver");
        drivers.add(addDriver);
        addDriver.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent arg0) {
                new AddDriverFrame(getXBound(), getYBound());
            }
        });
        JMenuItem viewDrivers = new JMenuItem("View / Edit Drivers");
        viewDrivers.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent arg0) {
                new ViewDriversFrame(getXBound(), getYBound());
            }
        });
        drivers.add(viewDrivers);

        drivers.add(new JSeparator());
        JMenuItem addTimeSlot = new JMenuItem("Add Time Slot");
        addTimeSlot.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent arg0) {
                new AddTimeSlotFrame(getXBound(), getYBound());
            }
        });
        drivers.add(addTimeSlot);

        JMenuItem viewTimeSlots = new JMenuItem("View / Edit Time Slots");
        viewTimeSlots.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent arg0) {
                new ViewTimeSlotsFrame(getXBound(), getYBound());
            }
        });
        drivers.add(viewTimeSlots);

        JMenu vehicles = new JMenu("Vehicles");

        JMenuItem addVehicle = new JMenuItem("Add Vehicle");
        addVehicle.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent arg0) {
                new AddVehicleFrame(getXBound(), getYBound());
            }
        });
        vehicles.add(addVehicle);
        JMenuItem viewVehicles = new JMenuItem("View / Edit Vehicles");
        viewVehicles.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent arg0) {
                new ViewVehiclesFrame(getXBound(), getYBound());
            }
        });
        vehicles.add(viewVehicles);
        vehicles.add(new JSeparator());

        JMenuItem addVehicleType = new JMenuItem("Add Vehicle Type");
        addVehicleType.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent arg0) {
                new AddVehicleTypeFrame(getXBound() + 50, getYBound() + 50);
            }
        });
        vehicles.add(addVehicleType);

        JMenuItem viewVehicleTypes = new JMenuItem("View / Edit Vehicle Types");
        viewVehicleTypes.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                new ViewVehicleTypesFrame(getXBound(), getYBound());
            }
        });
        vehicles.add(viewVehicleTypes);

        JMenu users = new JMenu("Users");
        JMenuItem addUser = new JMenuItem("Add User");
        users.add(addUser);
        JMenuItem viewUser = new JMenuItem("View / Edit Users");
        viewUser.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                new ViewUsersFrame(getX(), getY());
            }
        });
        users.add(viewUser);

        JMenu services = new JMenu("Services");
        JMenuItem viewServices = new JMenuItem("View Services");
        services.add(viewServices);


        menuBar.add(file);
        menuBar.add(drivers);
        menuBar.add(vehicles);
        menuBar.add(users);
        menuBar.add(services);
        this.setJMenuBar(menuBar);

        this.setVisible(true);

    }

    public static void main(String[] args) {
        new mainFrame();
    }

    public int getXBound() {
        return this.getX();
    }

    public int getYBound() {
        return this.getY();
    }

    public static void updateTable() {
        eventsList = EventDAO.getEventsByDate(new Date(cal.getTimeInMillis()));

        //EventHandler.sortEvents((ArrayList<Event>) eventsList, EventHandler.SORT_BY_DEPART_TIME);
        events = new Object[eventsList.size()][9];
        long depart, driveTime;
        for (int i = 0; i < eventsList.size(); i++) {
            events[i][0] = sdf.format(eventsList.get(i).getDate());
            events[i][1] = eventsList.get(i).getService().getDriveTime() + " mins";
            depart = eventsList.get(i).getService().getStartTime().getTime();
            driveTime = eventsList.get(i).getService().getDriveTime() * 60 * 1000;
            events[i][2] = sdf2.format(new Date(depart - driveTime));
            events[i][3] = eventsList.get(i).getDriver();
            events[i][4] = eventsList.get(i).getVehicle();
            events[i][5] = sdf2.format(eventsList.get(i).getService().getStartTime());
            events[i][6] = eventsList.get(i).getService().getLocation();
            events[i][7] = eventsList.get(i).getService().getTransnumb();
            depart = eventsList.get(i).getService().getEndTime().getTime();
            events[i][8] = sdf2.format(new Date(depart - driveTime));
        }
        model = new MyTableModel(events, columnNames);
        table = new myTable(model);
        table.setRowHeight(30);
        table.getTableHeader().setReorderingAllowed(false);
        //table.addRowSelectionInterval(0, 0);
        //TableColumn col = table.getColumnModel().getColumn(3);
        //col.setCellEditor(new customDriverEditor(new JComboBox(driverArray)));
        content.remove(scrollpane);
        scrollpane = new JScrollPane(table);
        scrollpane.setBounds(50, 50, 900, 400);
        content.add(scrollpane);
    }
}

class customDriverEditor extends DefaultCellEditor {

    public customDriverEditor(final JComboBox arg0) {

        super(arg0);

        this.addCellEditorListener(new CellEditorListener() {

            @Override
            public void editingStopped(ChangeEvent e) {
                if (mainFrame.table.getSelectedColumn() == 3) {
                    mainFrame.selectedIndex = arg0.getSelectedIndex();
                    Object[] options = {"Default Driver", "Substitute Driver", "Cancel"};
                    int choice = JOptionPane.showOptionDialog(getComponent(), "Set as Default Driver or Subsititute?", "Set as Default Driver?", JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE, null, options, options[2]);
                    switch (choice) {
                        case 0:
                            mainFrame.eventsList.get(mainFrame.table.getSelectedRow()).setDefaultDriverID(((Driver) arg0.getSelectedItem()).getId());
                            break;
                        case 2:
                            for (int i = 0; i < arg0.getItemCount(); i++) {
                                if (mainFrame.eventsList.get(mainFrame.table.getSelectedRow()).getDriver().toString().equals(arg0.getItemAt(i).toString())) {
                                    arg0.setSelectedIndex(i);
                                    mainFrame.table.setValueAt(mainFrame.eventsList.get(mainFrame.table.getSelectedRow()).getDriver(), mainFrame.table.getSelectedRow(), 3);
                                }
                            }
                            break;

                        default:
                            break;
                    }
                } else {
                    mainFrame.selectedIndex = arg0.getSelectedIndex();
                }
            }

            @Override
            public void editingCanceled(ChangeEvent e) {
                // TODO Auto-generated method stub
            }
        });
    }
}

class myTable extends JTable {

    public myTable(TableModel m) {
        super(m);
    }

    @Override
    public TableCellEditor getCellEditor(int row, int col) {

        Event e = mainFrame.eventsList.get(row);

        if (col == 3) {
            List<Driver> possDrivers = e.getPossibleDrivers();
            Driver[] possDriversArray = new Driver[possDrivers.size()];

            for (int i = 0; i < possDrivers.size(); i++) {
                possDriversArray[i] = possDrivers.get(i);
            }

            int index = 0;
            JComboBox box = new JComboBox(possDriversArray);
            for (int i = 0; i < possDriversArray.length; i++) {
                if (e.getDriver().toString().equals(possDriversArray[i].toString())) {
                    index = i;
                }
            }
            box.setSelectedIndex(index);

            return new customDriverEditor(box);
        } else if (col == 4) {
            List<Vehicle> possVehicles = VehicleDAO.getVehicles();
            Vehicle[] possVehiclesArray = new Vehicle[possVehicles.size()];

            for (int i = 0; i < possVehicles.size(); i++) {
                possVehiclesArray[i] = possVehicles.get(i);
            }

            int index = 0;
            JComboBox box = new JComboBox(possVehiclesArray);
            for (int i = 0; i < possVehiclesArray.length; i++) {
                if (e.getVehicle().toString().equals(possVehiclesArray[i].toString())) {
                    index = i;
                }
            }
            box.setSelectedIndex(index);

            return new customDriverEditor(box);
        } else {
            return null;
        }

    }
}
